home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / pbClock / ButtonsControl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-09  |  7.4 KB  |  350 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         buttonscontrol.c
  5. ** Written by:      Eric Soldan
  6. **
  7. ** Copyright © 1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #ifndef __CONTROLS__
  26. #include <Controls.h>
  27. #endif
  28.  
  29. #ifndef __ERRORS__
  30. #include <Errors.h>
  31. #endif
  32.  
  33. #ifndef __FONTS__
  34. #include <Fonts.h>
  35. #endif
  36.  
  37. #ifndef __MEMORY__
  38. #include <Memory.h>
  39. #endif
  40.  
  41. #ifndef __RESOURCES__
  42. #include <Resources.h>
  43. #endif
  44.  
  45. #ifndef __OSUTILS__
  46. #include <OSUtils.h>
  47. #endif
  48.  
  49. #ifndef __SCRIPT__
  50. #include <Script.h>
  51. #endif
  52.  
  53. #ifndef __STRINGUTILS__
  54. #include "StringUtils.h"
  55. #endif
  56.  
  57. #ifndef __UTILITIES__
  58. #include "Utilities.h"
  59. #endif
  60.  
  61. #ifndef __TEXTEDIT__
  62. #include <TextEdit.h>
  63. #endif
  64.  
  65.  
  66.  
  67. /*****************************************************************************/
  68.  
  69.  
  70.  
  71. void            DebugWindow(Str255 str);
  72.  
  73. static pascal long        ButtonsCtl(short varCode, ControlHandle ctl, short msg, long parm);
  74. void                    InitButtonsCtl(short viewID);
  75. Boolean                    IsButtonsCtl(ControlHandle ctl);
  76. static pascal void        NoRect(GrafVerb verb, Rect *r);
  77. static void                GetRects(Rect rct, Rect *tr, Rect *r);
  78.  
  79. #ifdef powerc
  80. #pragma options align=mac68k
  81. #endif
  82. typedef struct cdefRsrcJMP {
  83.     long    jsrInst;
  84.     long    mmemInst;
  85.     short    mregInst;
  86.     short    beqInst;
  87.     short    jmpInst;
  88.     long    jmpAddress;
  89. } cdefRsrcJMP;
  90. typedef cdefRsrcJMP *cdefRsrcJMPPtr, **cdefRsrcJMPHndl;
  91. #ifdef powerc
  92. #pragma options align=reset
  93. #endif
  94.  
  95. static cdefRsrcJMPHndl    gButtonsCDEF;
  96.  
  97.  
  98.  
  99. /*****************************************************************************/
  100. /*****************************************************************************/
  101.  
  102.  
  103.  
  104. #pragma segment Controls
  105. static pascal long    ButtonsCtl(short varCode, ControlHandle ctl, short msg, long parm)
  106. {
  107.     Rect        rct, r, tr;
  108.     WindowPtr    ww;
  109.     short        txFont, txSize, txMode, ascent, i, dev;
  110.     Style        txFace;
  111.     FontInfo    finfo;
  112.     Str255        str;
  113.     QDProcs        qdp;
  114.     QDProcsPtr    oldqdp;
  115.     RgnHandle    oldClip, bwClip, clClip;
  116.     RGBColor    oldrgb;
  117.  
  118.     static QDRectUPP    qdrupp;
  119.     static RGBColor        grayrgb  = {0x8000, 0x8000, 0x8000};
  120.  
  121.     rct = (*ctl)->contrlRect;
  122.     GetPort(&ww);
  123.  
  124.     switch (msg) {
  125.  
  126.         case drawCntl:
  127.             txFont = ww->txFont;
  128.             txSize = ww->txSize;
  129.             txFace = ww->txFace;
  130.             txMode = ww->txMode;
  131.             GetFontInfo(&finfo);
  132.             ascent = (finfo.ascent - finfo.descent) / 2;
  133.             if (!(varCode & 0x08)) {
  134.                 TextFont(systemFont);
  135.                 TextFace(normal);
  136.                 TextSize(0);
  137.                 ascent = 4;
  138.             }
  139.             switch (varCode & 0x07) {
  140.                 case checkBoxProc:
  141.                 case radioButProc:
  142.                     GetRects(rct, &tr, &r);
  143.                     GetFontInfo(&finfo);
  144.                     tr.bottom = tr.top + (tr.bottom - tr.top + 1) / 2;
  145.                     i = (finfo.ascent + finfo.descent);
  146.                     tr.bottom += (i / 2);
  147.                     tr.top     = tr.bottom - i;
  148.                     pcpy(str, (*ctl)->contrlTitle);
  149.  
  150.                     oldqdp = ww->grafProcs;
  151.                     if (oldqdp)
  152.                         BlockMove(oldqdp, &qdp, sizeof(QDProcs));
  153.                     else
  154.                         SetStdProcs(&qdp);
  155.                     if (!qdrupp) {
  156. #if USES68KINLINES
  157.                         qdrupp = (QDRectUPP)NoRect;
  158. #else
  159.                         qdrupp = NewQDRectProc(NoRect);
  160. #endif
  161.                     }
  162.                     qdp.rectProc = qdrupp;
  163.                     ww->grafProcs = &qdp;
  164.  
  165.                     TextMode(srcOr);
  166.                     TETextBox(str + 1, str[0], &tr, teFlushDefault);
  167.                     TextMode(txMode);
  168.                     ww->grafProcs = oldqdp;
  169.                     GetClip(oldClip = NewRgn());
  170.                     if ((*ctl)->contrlHilite == 255) {
  171.                         bwClip = LocalScreenDepthRegion(1);
  172.                         clClip = LocalScreenDepthRegion(4);
  173.                         DiffRgn(bwClip, clClip, bwClip);
  174.                         SectRgn(bwClip, oldClip, bwClip);
  175.                         SectRgn(clClip, oldClip, clClip);
  176.                     }
  177.                     else {
  178.                         CopyRgn(oldClip, bwClip = NewRgn());
  179.                         clClip = NewRgn();
  180.                     }
  181.                     for (dev = 0; dev < 2; ++dev) {
  182.                         if (!dev) {
  183.                             if (EmptyRgn(bwClip)) continue;
  184.                             SetClip(bwClip);
  185.                             if ((*ctl)->contrlHilite == 255) PenPat((ConstPatternParam)&qd.gray);
  186.                         }
  187.                         if (dev) {
  188.                             if (EmptyRgn(clClip)) continue;
  189.                             SetClip(clClip);
  190.                             if ((*ctl)->contrlHilite == 255) {
  191.                                 GetForeColor(&oldrgb);
  192.                                 RGBForeColor(&grayrgb);
  193.                             }
  194.                         }
  195.                         if ((*ctl)->contrlHilite == 0x01) PenSize(2, 2);
  196.                         if ((varCode & 0x07) == radioButProc) {
  197.                             EraseOval(&r);
  198.                             FrameOval(&r);
  199.                             PenSize(1, 1);
  200.                             if ((*ctl)->contrlValue) {
  201.                                 InsetRect(&r, 3, 3);
  202.                                 PaintOval(&r);
  203.                                 InsetRect(&r, -3, -3);
  204.                             }
  205.                         }
  206.                         else {
  207.                             EraseRect(&r);
  208.                             FrameRect(&r);
  209.                             PenSize(1, 1);
  210.                             if ((*ctl)->contrlValue) {
  211.                                 MoveTo(r.left,      r.top);
  212.                                 LineTo(r.right - 1, r.bottom - 1);
  213.                                 MoveTo(r.right - 1, r.top);
  214.                                 LineTo(r.left,      r.bottom - 1);
  215.                             }
  216.                         }
  217.                         if (dev)
  218.                             if ((*ctl)->contrlHilite == 255)
  219.                                 RGBForeColor(&oldrgb);
  220.                         PenNormal();
  221.                     }
  222.                     SetClip(oldClip);
  223.                     DisposeRgn(oldClip);
  224.                     DisposeRgn(bwClip);
  225.                     DisposeRgn(clClip);
  226.                     break;
  227.             }
  228.             break;
  229.  
  230.         case testCntl:
  231.             if ((*ctl)->contrlHilite == 255) return(0);
  232.                 /* Control disabled, so no click.  We probably don't get called in this case. */
  233.             return(PtInRect(*(Point *)&parm, &rct));
  234.             break;
  235.  
  236.         case calcCRgns:
  237.         case calcCntlRgn:
  238.         case calcThumbRgn:
  239.             if (msg == calcCRgns) parm &= 0x00FFFFFF;
  240.             RectRgn((RgnHandle)parm, &rct);
  241.             if (msg != calcCRgns) return(1);
  242.             break;
  243.  
  244.         case initCntl:
  245.             break;
  246.  
  247.         case dispCntl:
  248.             break;
  249.  
  250.         case posCntl:
  251.             break;
  252.  
  253.         case thumbCntl:
  254.             break;
  255.  
  256.         case dragCntl:
  257.             break;
  258.  
  259.         case autoTrack:
  260.             break;
  261.     }
  262.  
  263.     return(0);
  264. }
  265.  
  266.  
  267.  
  268. /*****************************************************************************/
  269.  
  270.  
  271.  
  272. #pragma segment Controls
  273. void    InitButtonsCtl(short viewID)
  274. {
  275.     static ControlDefUPP    cdefupp;
  276.  
  277.     if (!gButtonsCDEF) {
  278.         gButtonsCDEF = (cdefRsrcJMPHndl)GetResource('CDEF', (viewID / 16));
  279.         if (gButtonsCDEF) {
  280.             if (!cdefupp) {
  281.                 cdefupp = NewControlDefProc(ButtonsCtl);
  282.             }
  283.             (*gButtonsCDEF)->jmpAddress = (long)cdefupp;
  284.             if (TrapExists(_HWPriv))
  285.                 FlushInstructionCache();
  286.                     /* Make sure that instruction caches don't kill us. */
  287.         }
  288.     }
  289. }
  290.  
  291.  
  292.  
  293. /*****************************************************************************/
  294.  
  295.  
  296.  
  297. #pragma segment Controls
  298. Boolean    IsButtonsCtl(ControlHandle ctl)
  299. {
  300.     if (ctl)
  301.         if (StripAddress((*ctl)->contrlDefProc) == StripAddress(gButtonsCDEF))
  302.             return(true);
  303.                 /* The handle may be locked, which means that the hi-bit
  304.                 ** may be on, thus invalidating the compare.  Dereference the
  305.                 ** handles to get rid of this possibility. */
  306.     return(false);
  307. }
  308.  
  309.  
  310.  
  311. /*****************************************************************************/
  312.  
  313.  
  314.  
  315. #pragma segment Controls
  316. static pascal void    NoRect(GrafVerb verb, Rect *r)
  317. {
  318. #ifndef __MWERKS__
  319. #pragma unused (verb, r)
  320. #endif
  321. }
  322.  
  323.  
  324.  
  325. /*****************************************************************************/
  326.  
  327.  
  328.  
  329. #pragma segment Controls
  330. static void    GetRects(Rect rct, Rect *tr, Rect *r)
  331. {
  332.     *tr = *r = rct;            /* Return text rect and indicator rect. */
  333.     r->top  = (r->top + (r->bottom - r->top + 1) / 2);
  334.     r->top -= 6;
  335.     r->bottom = r->top + 12;
  336.     if (!GetSysDirection()) {
  337.         r->left  += 2;
  338.         r->right  = r->left + 12;
  339.         tr->left  += 17;
  340.     }
  341.     else {
  342.         r->right -= 2;
  343.         r->left   = r->right - 12;
  344.         tr->right -= 17;
  345.     }
  346. }
  347.  
  348.  
  349.  
  350.